﻿using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEditor.Animations;
using UnityEngine;

public class CopePrefabsEditor : Editor
{
    [MenuItem("Tools/拷贝预设体及依赖资源")]
    private static void Copy()
    {
        GameObject[] arr =  Selection.GetFiltered<GameObject>(SelectionMode.Assets);
        foreach (var item in arr)
        {
            string dir = AssetDatabase.GetAssetPath(item);
            if (!dir.EndsWith("prefab"))
            {
                Debug.LogWarning("selected objects must be prefabs:" + dir);
                return;
            }
            string directoryPath = Path.Combine(Path.GetDirectoryName(dir), Path.GetFileNameWithoutExtension(dir));
            if (Directory.Exists(directoryPath))
            {
                Debug.LogWarning("directory path already existed:" + directoryPath);
            }
            else
            {
                Directory.CreateDirectory(directoryPath);
                Debug.Log(directoryPath);
            }
            //获取所有依赖
            string[] dependencies = AssetDatabase.GetDependencies(dir);
            List<string> listSourceFile = new List<string>();
            List<string> listDestClonedFile = new List<string>();
            Dictionary<string, string> dicSourceMaterial = new Dictionary<string, string>();
            foreach (var dependency in dependencies)
            {
                //Debug.Log(dependency);
                System.Type t = AssetDatabase.GetMainAssetTypeAtPath(dependency);
                //Debug.Log(t);
                if (t == typeof(GameObject))
                {
                    //File.Copy(dependency, Path.Combine(directoryPath, Path.GetFileName(dependency)));
                    if (dependency.EndsWith(".FBX") || dependency.EndsWith(".fbx"))
                    {
                        string destDir = Path.Combine(directoryPath, "FBX");
                        if (!Directory.Exists(dependency))
                            Directory.CreateDirectory(destDir);
                        string destFile = Path.Combine(destDir, Path.GetFileName(dependency));
                        if (!File.Exists(destFile))
                            File.Copy(dependency, destFile);
                        else
                            Debug.Log(destFile + "has existed!");
                        listSourceFile.Add(dependency);
                        listDestClonedFile.Add(destFile);
                    }
                    else if (dependency.EndsWith(".FBX") || dependency.EndsWith(".fbx")) 
                    {
                    
                    }
                    else
                    {
                        Debug.Log(dependency);
                        Debug.Log(t);
                    }
                }
                else if (t == typeof(AnimatorController))
                {
                    //copy asset
                    string destDir = Path.Combine(directoryPath, "Animator");
                    if (!Directory.Exists(dependency))
                        Directory.CreateDirectory(destDir);
                    string destFile = Path.Combine(destDir, Path.GetFileName(dependency));
                    if (!File.Exists(destFile))
                        File.Copy(dependency, destFile);
                    else
                        Debug.Log(destFile + "has existed!");
                    listSourceFile.Add(dependency);
                    listDestClonedFile.Add(destFile);
                }
                else if (t.BaseType == typeof(Texture))
                {
                    //copy asset
                    string destDir = Path.Combine(directoryPath, "Textures");
                    if (!Directory.Exists(dependency))
                        Directory.CreateDirectory(destDir);
                    string destFile = Path.Combine(destDir, Path.GetFileName(dependency));
                    if (!File.Exists(destFile))
                        File.Copy(dependency, destFile);
                    else
                        Debug.Log(destFile + "has existed!");
                    listSourceFile.Add(dependency);
                    listDestClonedFile.Add(destFile);
                }
                else if (t == typeof(Material))
                {
                    //copy asset
                    string destDir = Path.Combine(directoryPath, "Materials");
                    if (!Directory.Exists(dependency))
                        Directory.CreateDirectory(destDir);
                    string destFile = Path.Combine(destDir, Path.GetFileName(dependency));
                    if (!File.Exists(destFile))
                        File.Copy(dependency, destFile);
                    else
                        Debug.Log(destFile + "has existed!");
                    dicSourceMaterial.Add(destFile, File.ReadAllText(dependency));
                    listSourceFile.Add(dependency);
                    listDestClonedFile.Add(destFile);
                }
                else
                {
                    Debug.Log(dependency);
                    Debug.Log(t);
                }
            }
            //redirect prefab ref
            AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);
            StringBuilder builder1 = new StringBuilder();
            string line = string.Empty;
            using (StreamReader sr = new StreamReader(dir))
            {
                while ((line = sr.ReadLine()) != null)
                {
                    if (line.Contains("guid"))
                    {
                        for (int i = 0; i < listSourceFile.Count; i++)
                        {
                            string guidSource = AssetDatabase.AssetPathToGUID(listSourceFile[i]);
                            string guidCloned = AssetDatabase.AssetPathToGUID(listDestClonedFile[i]);
                            line = line.Replace(guidSource, guidCloned);
                        }
                    }
                    builder1.AppendLine(line);
                }
            }
            File.WriteAllText(Path.Combine(directoryPath, Path.GetFileName(dir)), builder1.ToString());
            //redirect materials ref
            foreach (var destPath_sourceMat in dicSourceMaterial)
            {
                string mat = destPath_sourceMat.Value;
                for (int i = 0; i < listSourceFile.Count; i++)
                {
                    string guidSource = AssetDatabase.AssetPathToGUID(listSourceFile[i]);
                    string guidCloned = AssetDatabase.AssetPathToGUID(listDestClonedFile[i]);
                    mat = mat.Replace(guidSource, guidCloned);
                }
                File.WriteAllText(destPath_sourceMat.Key, mat);
            }
        }
        AssetDatabase.Refresh();
    }
}
